#pragma once
#ifndef _GEOMETRY_2D_POINT_
#define _GEOMETRY_2D_POINT_

//================================================================================================================================
//================================================================================================================================
// QtCore
#include <QtCore/QTextStream>
// Локальные
#include "math/math.h"
#include "core_global.h"

//================================================================================================================================
//================================================================================================================================
namespace geometry
{
    namespace _2d
    {
        //! Точка в двумерном пространстве.
        class CORE_EXPORT Point
        {
        public:
            //! Создание точки с координатами (0;0).
            Point() : m_x(0.0), m_y(0.0){}

            //! Создание точки с заданными координатами.
            Point(double x, double y) : m_x(x), m_y(y){}

            double x() const {return m_x;}
            double y() const {return m_y;}
            void setX(double x) {m_x = x;}
            void setY(double y) {m_y = y;}

            //! Передвинуть точку на \e dx по горизонтали и на \e dy по вертикали относительно текущей позиции.
            void shift(double dx, double dy) {m_x += dx; m_y += dy;}

            //! Возвращает копию точки, передвинутую на \e dx по горизонтали и на \e dy по вертикали относительно текущей позиции.
            Point shifted(double dx, double dy) const {return Point(m_x + dx, m_y + dy);}

        private:
            double m_x;	//!< Первая координата точки.
            double m_y;	//!< Вторая координата точки.
        };

        //========================================================================================================================
        //========================================================================================================================
        //! Сравнение точек.
        //! \relates Point
        //! \remarks При проверке координат вектора на равенство, разность соответствующих компонент сравнивется с константой
        //! \e DBL_EPSILON, определённой в файле <float.h>. \e DBL_EPSILON - это минимальное значение, которое при прибавлении
        //! его к единице, меняет ее значение.
        inline bool operator==(const Point &p1, const Point &p2)
        {
            return qAbs(p1.x() - p2.x()) < DBL_EPSILON && qAbs(p1.y() - p2.y()) < DBL_EPSILON;
        }

        //! Сравнение точек.
        //! \relates Point
        //! \remarks При проверке координат вектора на равенство, разность соответствующих компонент сравнивется с константой
        //! \e DBL_EPSILON, определённой в файле <float.h>. \e DBL_EPSILON - это минимальное значение, которое при прибавлении
        //! его к единице, меняет ее значение.
        inline bool operator!=(const Point &p1, const Point &p2)
        {
            return qAbs(p1.x() - p2.x()) > DBL_EPSILON || qAbs(p1.y() - p2.y()) > DBL_EPSILON;
        }

        //========================================================================================================================
        //========================================================================================================================
        //! Вывод вектора в текстовый поток.
        //! \relates Point
        inline QTextStream& operator<<(QTextStream &stream, const Point &point)
        {
            stream << point.x() << " " << point.y();
            return stream;
        }

        //! Ввод вектора из текстового потока.
        //! \relates Point
        inline QTextStream& operator>>(QTextStream &stream, Point &point)
        {
            double x, y;
            stream >> x >> y;
            point.setX(x);
            point.setY(y);
            return stream;
        }
    }
}

#endif // _GEOMETRY_2D_POINT_
